﻿#region Librerias

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.IO;

#endregion


namespace ESF.General
{
	public class BaseTaskManager
	{
		#region Members

		private int _ItemWorkCount;

		private int _ItemReadyCount;

		private int _ItemErrorCount;

		private Stopwatch _SWatch;

		protected TextWriter LogWriter;

		protected CancellationTokenSource CancelTokenSource { private set; get; }

		#endregion


		#region Delegados

		protected ProcessHelper.ReportProgressDelegate ReportProgressDelegate;

		#endregion


		#region Propiedades
		
		public int ItemWorkCount { get { return _ItemWorkCount; } }

		public int ItemReadyCount { get { return _ItemReadyCount; } }

		public int ItemErrorCount { get { return _ItemErrorCount; } }

		#endregion


		#region Constructor
		
		public BaseTaskManager (ProcessHelper.ReportProgressDelegate pdelReportProgressDelegate = null)
		{
			ReportProgressDelegate = pdelReportProgressDelegate;

			_SWatch = new Stopwatch ();
		}

		#endregion


		#region Funciones

		protected void InitializeLog (string pLogFileName)
		{
			if (!string.IsNullOrEmpty (pLogFileName))
			{
				pLogFileName = Path.GetTempFileName () + ".txt";
			}

			LogWriter = TextWriter.Synchronized (new StreamWriter (pLogFileName));
		}


		protected void IncrementReadyCount ()
		{
			Interlocked.Increment (ref _ItemReadyCount);
		}


		protected void IncrementErrorCount (Exception pEx)
		{
			Log.Error (pEx);

			Interlocked.Increment (ref _ItemErrorCount);
		}


		protected void InitializeReadyCount (int pValue = 0)
		{
			_ItemReadyCount = pValue;

			ReportProgress ();
		}


		public void Start(int pWorkCount = 0)
		{
			_ItemWorkCount = pWorkCount;
			_ItemReadyCount = 0;
			_ItemErrorCount = 0;

			ReportProgress ("Iniciando ejecución");

			_SWatch.Start ();

			CancelTokenSource = new CancellationTokenSource ();
		}


		public virtual void Stop ()
		{
			ReportProgress ();

			_SWatch.Stop ();

			if (LogWriter != null)
			{
				LogWriter.Close ();
			}
		}


		public virtual void Cancel ()
		{
			CancelTokenSource.Cancel ();

			Stop ();
		}


		public void ReportProgress(string pMessage = "", long pItemElapsedMs = 0)
		{
			if (ReportProgressDelegate != null)
			{
				ReportProgressDelegate(pMessage, ItemWorkCount, ItemReadyCount, ItemErrorCount, pItemElapsedMs);
			}
		}

		#endregion
	}
}
